<html>
<head>
  <script src="../OLLoader.js"></script>
  <script type="text/javascript">

    function test_initialize(t) {
        
        t.plan(1);
        
        var map = new OpenLayers.Map("map");
        var control = new OpenLayers.Control.Measure(
            OpenLayers.Handler.Path, {persist: true}
        );
        map.addControl(control);
        
        t.eq(control.persist, true, "passing persist to constructor sets persist on handler");
        
        map.destroy();
        
    }
    
    function test_cancel(t) {
        
        t.plan(4);
        
        var map = new OpenLayers.Map("map");
        var layer = new OpenLayers.Layer(null, {
            isBaseLayer: true
        });
        map.addLayer(layer);
        map.zoomToMaxExtent();
        
        var control = new OpenLayers.Control.Measure(
            OpenLayers.Handler.Path, {persist: true}
        );
        map.addControl(control);
        
        control.activate();

        try {
            control.cancel();
            t.ok(true, "calling cancel before drawing works");
        } catch(err) {
            t.fail("calling cancel before drawing causes trouble: " + err);
        }
        t.eq(control.active, true, "control remains active after cancel");
        
        // create a simple measurement
        function trigger(type, x, y) {
            map.events.triggerEvent(type, {
                xy: new OpenLayers.Pixel(x, y)
            })
        };

        trigger("mousemove", 0, 0);
        // keep a reference to the line being drawn
        var line = control.handler.line;
        trigger("mousedown", 0, 0);
        trigger("mouseup", 0, 0);
        trigger("mousemove", 10, 10);
        trigger("mousedown", 10, 10);
        trigger("mouseup", 10, 10);
        trigger("dblclick", 10, 10);

        // the geometry is finalized, we first confirm that it is persisted
        t.ok(line.layer === control.handler.layer, "feature persists");
        
        // cancel and see that sketch is gone
        control.cancel();
        t.eq(line.layer, null, "feature is gone after cancel");

        map.destroy();
    }

    // test for <http://trac.openlayers.org/ticket/2691>
    function test_partial(t) {        

        t.plan(28);        
        
        var map = new OpenLayers.Map({
            div: "map",
            units: "m",
            resolutions: [1],
            layers: [
                new OpenLayers.Layer(null, {
                    isBaseLayer: true
                })
            ],
            center: new OpenLayers.LonLat(0, 0)
        });

        var log = [];
        var control = new OpenLayers.Control.Measure(
            OpenLayers.Handler.Path, {persist: true, 
                eventListeners: {
                    measurepartial: function(evt) {
                        log.push(evt);
                    },
                    measure: function(evt){
                        log.push(evt);
                    }
                },
                handlerOptions: {
                    pixelTolerance: 0,
                    dblclickTolerance: 0
                }
            }
        );
        map.addControl(control);
        control.activate();
        
        
        // convenience function to trigger mouse events
        function trigger(type, x, y) {
            map.events.triggerEvent(type, {
                xy: new OpenLayers.Pixel(x, y)
            })
        };
        
        // delay in seconds
        var delay = control.partialDelay / 1000;
        
        // establish first point
        trigger("mousemove", 0, 0);
        trigger("mousedown", 0, 0);
        trigger("mouseup", 0, 0);

        
        // a) move 10 pixels and click
        trigger("mousemove", 0, 10);
        trigger("mousedown", 0, 10);
        trigger("mouseup", 0, 10);
        
        // confirm measurepartial is not fired before delay
        t.eq(log.length, 0, "a) no event fired yet")

        t.delay_call( 
            // wait for delay then confirm event was logged
            delay, function() {
                t.eq(log.length, 1, "a) event logged")
                t.eq(log[0] && log[0].type, "measurepartial", "a) event logged");
                t.eq(log[0] && log[0].measure, 10, "a) correct measure");
                
                // b) move 10 pixels and click
                trigger("mousemove", 0, 20);
                trigger("mousedown", 0, 20);
                trigger("mouseup", 0, 20);
                
                // confirm measurepartial is not fired before delay
                t.eq(log.length, 1, "b) no event fired yet")
                
            },
            delay, function() {
                t.eq(log.length, 2, "b) event logged");
                t.eq(log[1] && log[1].type, "measurepartial", "b) correct type");
                t.eq(log[1] && log[1].measure, 20, "b) correct measure");

                // c) move 10 pixels and click
                trigger("mousemove", 0, 30);
                trigger("mousedown", 0, 30);
                trigger("mouseup", 0, 30);
            },
            // wait for half delay and confirm event not logged
            delay / 2, function() {
                // confirm measurepartial is not fired before delay
                t.eq(log.length, 2, "c) no event fired yet")
            },
            // wait for rest of delay and confirm event logged
            delay / 2, function() {
                t.eq(log.length, 3, "c) event logged");
                t.eq(log[2] && log[2].type, "measurepartial", "c) correct type");
                t.eq(log[2] && log[2].measure, 30, "c) correct measure");
                
                // d) move 10 pixels and click
                trigger("mousemove", 0, 40);
                trigger("mousedown", 0, 40);
                trigger("mouseup", 0, 40);

                // confirm measurepartial is not fired before delay
                t.eq(log.length, 3, "d) no event fired yet")
                
                // e) double click to finish
                trigger("dblclick", 0, 40);

                t.eq(log.length, 4, "e) event logged");
                t.eq(log[3] && log[3].type, "measure", "e) correct type");
                t.eq(log[3] && log[3].measure, 40, "e) correct measure");                
            },
            // wait for rest of delay and confirm no measurepartial logged
            delay, function() {
                // confirm measurepartial is not fired after dblclick
                t.eq(log.length, 4, "e) no additional event fired");
                
                // change to freehand mode and confirm synchronous event dispatch
                control.handler.freehand = true;
                // clear log
                log = [];
                
                // f) establish first freehand point
                trigger("mousemove", 0, 0);
                trigger("mousedown", 0, 0);
                t.eq(log.length, 0, "f) no event fired yet")
                
                // g) move 10 pixels
                trigger("mousemove", 10, 0);

                t.eq(log.length, 1, "g) event logged");
                t.eq(log[0] && log[0].type, "measurepartial", "g) correct type");
                t.eq(log[0] && log[0].measure, 10, "g) correct measure");
                
                // h) move 10 pixels
                trigger("mousemove", 20, 0);

                t.eq(log.length, 2, "h) event logged");
                t.eq(log[1] && log[1].type, "measurepartial", "h) correct type");
                t.eq(log[1] && log[1].measure, 20, "h) correct measure");

                // i) mouse up to finish
                trigger("mouseup", 20, 0);

                t.eq(log.length, 3, "i) event logged");
                t.eq(log[2] && log[2].type, "measure", "i) correct type");
                t.eq(log[2] && log[2].measure, 20, "i) correct measure");

                // j) clean up
                log = [];
                map.destroy();
            },
            // wait for delay and confirm event not logged
            delay, function() {
                t.eq(log.length, 0, "j) no event fired after destroy");
            }
        );
        
    }

    function test_immediate(t) {
        t.plan(32);
        
        var map = new OpenLayers.Map({
            div: "map",
            units: "m",
            resolutions: [1],
            layers: [
                new OpenLayers.Layer(null, {
                    isBaseLayer: true
                })
            ],
            center: new OpenLayers.LonLat(0, 0)
        });

        var log = [];
        var control = new OpenLayers.Control.Measure(
            OpenLayers.Handler.Path, {
                persist: true,
                immediate: true,
                eventListeners: {
                    measurepartial: function(evt) {
                        log.push(evt);
                    },
                    measure: function(evt){
                        log.push(evt);
                    }
                },
                handlerOptions: {
                    pixelTolerance: 0,
                    dblclickTolerance: 0
                }
            }
        );
        map.addControl(control);
        control.activate();

        // convenience function to trigger mouse events
        function trigger(type, x, y) {
            map.events.triggerEvent(type, {
                xy: new OpenLayers.Pixel(x, y)
            })
        };

        // delay in seconds
        var delay = control.partialDelay / 1000;

        // a) establish first point
        trigger("mousemove", 0, 0);
        trigger("mousedown", 0, 0);
        trigger("mouseup", 0, 0);

        // move 10 pixels
        trigger("mousemove", 0, 10);

        t.eq(log.length, 1, "a) has fired an event");

        t.delay_call(
            delay, function() {
                // confirm measurepartial is fired
                t.eq(log.length, 1, "a) one event logged");
                t.ok(log[0] && log[0].type == "measurepartial", "a) correct type");
                // mousemove within the partialDelay fires no event, so the
                // measure below is the one of the initial point
                t.eq(log[0]?log[0].measure:-1 , 10, "a) correct measure");

                // b) move 10 pixels
                trigger("mousemove", 0, 20);
                // c) move 10 pixels again
                trigger("mousemove", 0, 30);

                // confirm measurepartial is fired 2 times
                t.eq(log.length, 3, "b) event logged");
                t.eq(log[1] && log[1].type, "measurepartial", "b) correct type");
                t.eq(log[1] && log[1].measure, 20, "b) correct measure");
                t.eq(log[2] && log[2].type, "measurepartial", "c) correct type");
                t.eq(log[2] && log[2].measure, 30, "c) correct measure");

                // d) switch immediate measurement off
                control.setImmediate(false);
                t.eq(control.immediate, false, "d) immediate is false");

                // e) move 10 pixels and click
                trigger("mousemove", 0, 40);
                trigger("mousedown", 0, 40);
                trigger("mouseup", 0, 40);
                // confirm measurepartial is not fired before delay
                t.eq(log.length, 3, "e) no event fired yet")
            },
            // wait for delay then confirm event was logged
            delay, function() {
                t.eq(log.length, 4, "e) event logged")
                t.ok(log[3] && log[3].type == "measurepartial", "e) correct type");
                t.ok(log[3] && log[3].measure == 40, "e) correct measure");

                // f) switch immediate measurement on
                control.setImmediate(true);
                t.eq(control.immediate, true, "f) immediate is true");

                // g) move 10 pixels
                trigger("mousemove", 0, 50);
            },
            delay, function() {
                t.eq(log.length, 5, "g) event logged");
                t.ok(log[4] && log[4].type == "measurepartial", "g) correct type");
                t.ok(log[4] && log[4].measure == 50, "g) correct measure");

                // h) move 10 pixels
                trigger("mousemove", 0, 60);

                t.eq(log.length, 6, "h) event logged");
                t.ok(log[5] && log[5].type == "measurepartial", "h) correct type");
                t.ok(log[5] && log[5].measure == 60, "h) correct measure");

                // i) double click to finish
                trigger("mousedown", 0, 60);
                t.eq(log.length, 7, "i) event logged");
                t.eq(log[6] && log[6].type, "measurepartial", "i) correct type");
                t.eq(log[6] && log[6].measure, 60, "i) correct measure");
                trigger("mouseup", 0, 60);
                t.eq(log.length, 7, "i) no event fired yet");
            },
            delay, function() {
                t.eq(log.length, 8, "j) event logged");
                t.eq(log[7] && log[7].type, "measurepartial", "j) correct type");
                t.eq(log[7] && log[7].measure, 60, "j) correct measure");

                trigger("dblclick", 0, 60);
                t.eq(log.length, 9, "k) event logged");
                t.eq(log[8] && log[8].type, "measure", "k) correct type");
                t.eq(log[8] && log[8].measure, 60, "k) correct measure");
                // clear log
                log = [];

                // l) clean up
                map.destroy();
                // wait for delay and confirm event not logged
            },
            delay, function() {
                t.eq(log.length, 0, "l) no event fired after destroy");
            }
        );
    }
    
  </script>
</head>
<body>
    <div id="map" style="width: 512px; height: 256px;"></div>
</body>
</html>
